using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public static class CtrlEventID
{
    public const int EVENT_CONNECT_DATA_CENTER = 2000001;
    public const int EVENT_CONNECT_CTRL = 2000003;
    public const int EVENT_DATA_FACTORY_DATA_CHANGED = 2000004;
    public const int EVENT_QUERY_DATA_FACTORY_DATA = 2000005;

    public const int LOG_MANAGER_ID = 4000001;
    public const int ROOM_MANAGER_ID = 4000002;
}

public interface IDataBinder
{
    int DataFactoryId { get; }
    void Bind(object data);
}

public abstract class CtrlEventHandler : MonoBehaviour,IDataBinder
{
    public abstract int DataFactoryId { get; }
    public GameObject GameObject { get; private set; }
    public Transform Transform { get; private set; }
    public RectTransform RectTransform { get; private set; }

    public abstract void Bind(object data);

    void Awake()
    {
        GameObject = this.gameObject;
        Transform = this.transform;
        RectTransform = GetComponent<RectTransform>();
    }
}

public class ScriptBinderView : MonoBehaviour
{
    public int EventDataTypeID
    {
        get
        {
            if (null != m_template)
                return m_template.DataFactoryId;
            return 0;
        }
    }
    [SerializeField]
    ScrollRect m_scrollView;
    [SerializeField]
    CtrlEventHandler m_template;
    [SerializeField]
    [Range(0, 100)]
    int m_maxItem = 12;
    [SerializeField]
    [Range(0, 24)]
    int spacing = 8;
    [SerializeField]
    [Range(0, 24)]
    int topPadding = 12;
    [SerializeField]
    [Range(0, 24)]
    int bottomPadding = 12;
    InfinityScrollList scrollList;
    bool listDirty;

    private void Awake()
    {
        listDirty = false;
        scrollList = new InfinityScrollList(m_scrollView, topPadding,spacing, bottomPadding);
    }

    private void OnEnable()
    {
        EventDispatchManager.Instance.AddEvent(CtrlEventID.EVENT_DATA_FACTORY_DATA_CHANGED, OnDataChanged);
    }

    private void Start()
    {
        if(null == m_template)
        {
            Debug.Log($"{this.transform.parent.gameObject.name}");
            return;
        }
        scrollList.Init(m_template.gameObject, m_maxItem, 0, OnHandleCtrlEvent);
        EventDispatchManager.Instance.SendEvent(CtrlEventID.EVENT_QUERY_DATA_FACTORY_DATA, EventDataTypeID);
    }

    private void OnDisable()
    {
        EventDispatchManager.Instance.RemoveEvent(CtrlEventID.EVENT_DATA_FACTORY_DATA_CHANGED, OnDataChanged);
    }

    public void ScrollTo(int index)
    {
        scrollList.ScrollTo(index);
        listDirty = true;
    }

    void OnDataChanged(IEventArgv eventArgv)
    {
        if(eventArgv is EventArgv<int,int> argv && argv.a == EventDataTypeID)
        {
            scrollList.DataCount = argv.b;
            listDirty = true;
        }
    }

    void OnHandleCtrlEvent(CtrlEventHandler ctrlHandler,int index)
    {
        EventDispatchManager.Instance.SendEvent(CtrlEventID.EVENT_CONNECT_CTRL,ctrlHandler,index);
    }

    void OnValidate()
    {
        listDirty = true;
    }

    private void Update()
    {
        if(this.listDirty)
        {
            listDirty = false;
            scrollList.UpdateContent();
        }
    }
}
